---
title: Hooks API
description: Learn how to interact with the in-app URL in Expo Router.
---

import { APIBox } from '~/components/plugins/APIBox';
import { FileTree } from '~/ui/components/FileTree';
import { RouteUrlGroup, RouteUrl } from '~/ui/components/RouteUrl';

<RouteUrlGroup>

In Expo Router, there's always a valid URL that represents the currently focused route. Use hooks to observe changes and interact with the URL.

## Hooks

<APIBox header="useFocusEffect">

Given a function, the `useFocusEffect` hook will invoke the function whenever the route is "focused".

```tsx
/* @info */
import { useFocusEffect } from 'expo-router';
/* @end */
import { useCallback } from 'react';

export default function Route() {
  useFocusEffect(
    /* @info Callback should be wrapped in `React.useCallback` to avoid running the effect too often */
    useCallback(() => {
    /* @end */
      /* @info Invoked whenever the route is focused */
      console.log('Hello, I am focused!');
      /* @end */

      /* @info Return function is invoked whenever the route gets out of focus */
      return () => {
        console.log('This route is now unfocused.');
      }
      /* @end */
    }, [])
  );

  return </>;
}
```

</APIBox>

<APIBox header="useGlobalSearchParams">

Returns the URL parameters for the globally selected route. For example, `/acme?foo=bar` -> `{ foo: "bar" }`.

For dynamic routes, both the route parameters and the search parameters are returned.

Refer to the [local vs global URL params](/router/reference/url-parameters/#local-versus-global-url-parameters) guide for more information.

<RouteUrl>/profile/baconbrix?extra=info</RouteUrl>

```tsx app/profile/[user].tsx
import { Text } from 'react-native';
/* @info */
import { useGlobalSearchParams } from 'expo-router';
/* @end */

export default function Route() {
  /* @info <b>user=baconbrix</b> & <b>extra=info</b> */
  const { user, extra } = useGlobalSearchParams();
  /* @end */

  return <Text>User: {user}</Text>;
}
```

</APIBox>

<APIBox header="useLocalSearchParams">

Returns the URL parameters for the contextually selected route. Refer to the [local versus global URL params](/router/reference/url-parameters/#local-versus-global-url-parameters) guide for more information.

For dynamic routes, both the route parameters and the search parameters are returned.

<FileTree files={['app/_layout.tsx', 'app/[first]/home.tsx', 'app/[second]/shop.tsx']} />

When `/abc/home` pushes `/123/shop`, `useGlobalSearchParams` returns `{ first: undefined, second: '123' }` on **/app/[first]/home.tsx** because the global URL has changed. However, you may want the params to remain `{ first: 'abc' }` to reflect the context of the screen. In this case, you can use `useLocalSearchParams` to ensure the params `{ first: 'abc' }` are still returned in **/app/[first]/home.tsx**.

<RouteUrl>/profile/baconbrix?extra=info</RouteUrl>

```tsx app/profile/[user].tsx
import { Text } from 'react-native';
/* @info */
import { useLocalSearchParams } from 'expo-router';
/* @end */

export default function Route() {
  /* @info */
  const { user, extra } = useLocalSearchParams();
  /* @end */

  return <Text>User: {user}</Text>;
}
```

</APIBox>

<APIBox header="useNavigation">

Access the underlying React Navigation [`navigation` prop](https://reactnavigation.org/docs/navigation-prop) to imperatively access layout-specific functionality like `navigation.dispatch(DrawerActions.openDrawer())` in a Drawer layout. [Learn more](https://reactnavigation.org/docs/navigation-prop/#navigator-dependent-functions).

```tsx
import { Text, View } from 'react-native';
/* @info */
import { useNavigation } from 'expo-router';
import { DrawerActions } from '@react-navigation/native';
/* @end */

export default function Route() {
  /* @info Access the current navigation object for the current route */
  const navigation = useNavigation();
  /* @end */

  return (
    <View>
      <Text
        onPress={() => {
          /* @info Open the drawer view */
          navigation.dispatch(DrawerActions.openDrawer());
          /* @end */
        }}>
        Open Drawer
      </Text>
    </View>
  );
}
```

When using nested layouts, you can access higher-order layouts by passing a secondary argument denoting the layout route. For example:

<FileTree
  files={[
    ['app/_layout.tsx', <code>useNavigation('/')</code>],
    ['app/orders/_layout.tsx', <code>useNavigation('/orders')</code>],
    ['app/orders/menu/_layout.tsx', <code>useNavigation('/orders/menu')</code>],
  ]}
/>

{/* prettier-ignore */}
```tsx app/orders/menu/index.tsx
import { useNavigation } from 'expo-router';

export default function MenuRoute() {
  const rootLayout = useNavigation('/');

  const ordersLayout = useNavigation('/orders');

  // Same as the default results of `useNavigation()` when invoked in this route.
  const parentLayout = useNavigation('/orders/menu');

  /* @hide ... */ /* @end */
}
```

If you attempt to access a layout that doesn't exist, an error such as `Could not find parent navigation with route "/non-existent".` is thrown.

</APIBox>

<APIBox header="usePathname">

Returns the currently selected route location without search parameters. For example, `/acme?foo=bar` -> `/acme`. Segments will be normalized: `/[id]?id=normal` -> `/normal`

<RouteUrl>/profile/baconbrix?extra=info</RouteUrl>

```tsx app/profile/[user].tsx
import { Text } from 'react-native';
/* @info */
import { usePathname } from 'expo-router';
/* @end */

export default function Route() {
  /* @info <b>pathname = "/profile/baconbrix"</b> */
  const pathname = usePathname();
  /* @end */

  return <Text>User: {user}</Text>;
}
```

</APIBox>

<APIBox header="useSegments">

Returns a list of segments for the currently selected route. Segments are not normalized so that they will be the same as the file path. For example, `/[id]?id=normal` -> `["[id]"]`.

```tsx app/profile/[user].tsx
import { Text } from 'react-native';
/* @info */
import { useSegments } from 'expo-router';
/* @end */

export default function Route() {
  /* @info <b>segments = ["profile", "[user]"]</b> */
  const segments = useSegments();
  /* @end */

  return <Text>Hello</Text>;
}
```

This function can be typed using an abstract of string arrays:

```tsx app/profile/[user].tsx
import { useSegments } from 'expo-router';

export default function Route() {
  /* @info */
  const segments = useSegments<['profile'] | ['profile', '[user]']>();
  /* @end */

  return </>
}
```

</APIBox>

## Types

<APIBox header="Href">

The `Href` type is a union of the following types:

- **string**: A full path like `/profile/settings` or a relative path like `../settings`.
- **object**: An object with a `pathname` and optional `params` object. The `pathname` can be a full path like `/profile/settings` or a relative path like `../settings`. The `params` can be an object of key/value pairs.

</APIBox>

</RouteUrlGroup>
